About QuickDraw 3D
QuickDraw 3D is a graphics library developed by Apple Computer that you can use to create, configure, and render three-dimensional objects. It is specifically designed to be useful to a wide range of software developers, from those with very little knowledge of 3D modeling concepts and rendering techniques to those with very extensive experience with those concepts and techniques.At the most basic level, you can use the file format and file-access routines provided by QuickDraw 3D to read and display 3D graphics created by some other application. For example, a word-processing application might want to import a picture created by a 3D modeling or image-capturing application. QuickDraw 3D supports the 3D Viewer, which you can use to display 3D data and objects in a window and allow users limited interaction with that data, without having to learn any of the core QuickDraw 3D application programming interfaces.
You can also use QuickDraw 3D for more sophisticated applications, such as interactive 3D modeling and rendering, animation, data visualization, or any of thousands of other ways of interpreting and displaying data in three (or more) dimensions. Figure 1-1 illustrates the kinds of images you can produce using QuickDraw 3D. It shows a texture, a wireframe model, and the result of applying the texture to that model. See also Color Plate 3 at the beginning of this book.
- Note
- See the chapter "3D Viewer" for complete information about the 3D viewer, as well as complete source code samples illustrating how to create and manage a viewer object.
![]()
Figure 1-1 A simple three-dimensional picture
Modeling and Rendering
To create images such as that shown in Figure 1-1, you typically engage in at least two distinguishable main tasks: modeling and rendering. Modeling is the process of creating a representation of real or abstract objects, and rendering is the process of creating an image (on the screen or some other medium) of a model. QuickDraw 3D subdivides each of these tasks into a number of subtasks.In QuickDraw 3D, modeling involves
In QuickDraw 3D, rendering involves
- creating, configuring, and positioning basic geometric objects and groups of geometric objects. QuickDraw 3D defines many basic types of geometric objects and a large number of ways to transform such objects.
- assigning sets of attributes (such as diffuse and specular colors) to objects and parts of objects.
- applying textures to surfaces of objects.
- configuring a model's lights and shading. QuickDraw 3D supplies four types of lights (ambient light, directional lights, spot lights, and point lights) and several types of shaders.
- specifying a camera position and type. A camera type is defined by a method of projecting the model onto a flat surface, called the view plane. QuickDraw 3D provides two types of cameras that use perspective projection (the aspect ratio and view plane cameras) and one type of camera that uses parallel projection (the orthographic camera).
- specifying a renderer or method of rendering. QuickDraw 3D provides a wireframe and an interactive renderer. Renderers support different styles of rendering (for example, points, edges, or filled shapes).
- creating a view (a collection of a group of lights, a camera, and a renderer and its styles) and rendering the model using the view to create an image.
Interacting
Often, modeling and rendering are not easily separable, particularly in applications that support interactive 3D modeling. When, for example, the user selects a sphere and drags it using the mouse or other pointing device, the application needs to change the model (reposition the sphere) and render a new image. (Indeed, the application may generate a series of new images to show the sphere changing location as the user drags it.) QuickDraw 3D supports a third main task, interacting with a model (that is, selecting and manipulating objects in the model).In QuickDraw 3D, interacting involves
QuickDraw 3D supplies an extensive set of routines that you can use to perform these tasks. For complete details, see the chapters "QuickDraw 3D Pointing Device Manager" and "Pick Objects."
- determining what kinds of pointing devices are available on a particular computer and possibly configuring one or more of those devices to control items in a 3D model (such as a camera or a light).
- identifying the objects in a model that are close to the cursor when the user clicks or drags in the model's image. This is called picking.
Extending QuickDraw 3D
QuickDraw 3D is designed to be easily extensible, so that you can, if necessary, add capabilities that are not part of the basic QuickDraw 3D feature set. For instance, you've already seen that QuickDraw 3D supplies two types of renderers, the wireframe and interactive renderers. The wireframe renderer creates line renderings of models, as illustrated in Figure 1-2.Figure 1-2 A model rendered by the wireframe renderer
The interactive renderer uses a more complex rendering algorithm that allows illumination and shading effects to be produced. Figure 1-3 shows the same teapot model rendered by the interactive renderer.
Figure 1-3 A model rendered by the interactive renderer
QuickDraw 3D is extensible:
In addition, QuickDraw 3D is designed to be portable to other software platforms and to support a variety of hardware accelerators:
- You can define custom attributes and assign them to shapes or sets.
Finally, QuickDraw 3D defines a platform-independent metafile (that is, a file format) for storing and interchanging 3D data. This metafile is intended to provide a standard format according to which applications can read and write 3D data, even applications that use 3D graphics systems other than QuickDraw 3D. QuickDraw 3D itself includes routines that you can use to read and write data in the metafile format. Apple Computer, Inc. also supplies a parser that you can use to read and write metafile data on operating systems that do not support QuickDraw 3D.
- QuickDraw 3D is cross-platform. It is available on the Macintosh Operating System and will be available on other operating systems that use alternative window systems as well. This portability to other window systems is accomplished by isolating all window system-specific information into a layer called a draw context, which is associated with a view. QuickDraw 3D automatically handles system-dependent issues such as byte ordering.
- QuickDraw 3D renderers can take advantage of hardware accelerators, if available.
Figure 1-4 shows the functional components of QuickDraw 3D.
Figure 1-4 The parts of QuickDraw 3D
Naming Conventions
The QuickDraw 3D application programming interfaces are designed, as much as possible, to mirror the QuickDraw 3D class hierarchy described in the chapter "QuickDraw 3D Objects." They are also designed to exhibit as much uniformity as can reasonably be achieved by names describing a large and heterogeneous collection of objects instantiating classes in that hierarchy. Ideally, once you are acquainted with the various conventions governing the programming interfaces and the class hierarchy, you should be able to make correct guesses about the names of constants, data structures, and routines. In very many cases, the names of constants and routines are largely self-documenting, thanks to a strict adherence to the naming conventions. This section describes those conventions and provides some examples.Constants
All constants defined in the QuickDraw 3D application programming interfaces have the prefixkQ3
. Very simple constants consist solely of thekQ3
prefix and a specific value indicator. Here are some examples:
typedef enum TQ3Boolean { kQ3False, kQ3True } TQ3Boolean; typedef enum TQ3Status { kQ3Failure, kQ3Success } TQ3Status;Most other enumerated constants consist of the standardkQ3
prefix, followed by a type, followed by a specific value. Here are some examples:
typedef enum TQ3Axis { kQ3AxisX, kQ3AxisY, kQ3AxisZ } TQ3Axis;Other constants are defined using the C preprocessor#define
mechanism. Here are some examples:
#define kQ3ObjectTypeElement Q3_OBJECT_TYPE('e','l','m','n') #define kQ3ObjectTypePick Q3_OBJECT_TYPE('p','i','c','k') #define kQ3ObjectTypeShared Q3_OBJECT_TYPE('s','h','r','d') #define kQ3ObjectTypeView Q3_OBJECT_TYPE('v','i','e','w') #define kQ3ObjectTypeInvalid 0In general, these kinds of constants specify types of objects in the QuickDraw 3D class hierarchy or methods defining the behaviors of those types. These constants use the macrosQ3_OBJECT_TYPE
orQ3_METHOD_TYPE
. See page 3-34 for a definition of these macros.Data Types
All data structures and data types defined in the QuickDraw 3D application programming interfaces have the prefixTQ3
. Like constant names, data type names never contain the underscore character (_
). When emphasis is required, subwords of a data type name are capitalized and usually proceed from general to specific.There are four distinguishable classes in data type names.
- Opaque objects, whose definitions are private, begin with the prefix
TQ3
and end with the suffixObject
. Between the prefix and the suffix are one or more words indicating the type of the opaque object. Here are some examples:
TQ3GeometryObject TQ3ViewObject TQ3CameraObject TQ3StyleObject TQ3DrawContextObject
- Data structures used in defining characteristics of opaque objects begin with the prefix
TQ3
and end with the suffixData
. Between the prefix and the suffix are one or more words indicating the type of the object. Here are some examples:
TQ3TriangleData TQ3BoxData TQ3OrthographicCameraData
- Data structures that contain data not specifically used to define characteristics of an opaque object begin with the prefix
TQ3
. Following the prefix are one or more words indicating the type of the data the structure contains. Here are some examples:
TQ3Point3D TQ3Vector2D TQ3ColorRGB TQ3ColorARGB
- Attributes are opaque objects, but they are named differently to distinguish them from other opaque objects. Attributes are of type
TQ3Attribute
.
- IMPORTANT
- All floating-point numbers used in the QuickDraw 3D application programming interfaces are single precision.
![]()
Functions
All functions defined in the QuickDraw 3D application programming interfaces have the prefixQ3
. The class of an identifier immediately follows its type prefix. Then the method occurs, separated from the class by an underscore. A method is almost always expressed as a verb-noun sequence. Here are some examples:
Q3Polygon_GetVertexPosition Q3NURBCurve_SetControlPoint Q3Light_SetBrightness Q3SpotLight_GetFallOff Q3View_GetLocalToWorldInverseTransposeMatrixState Q3Triangle_NewSome functions are so simple that they have no distinguishable class and method. Here are some examples:
Q3Initialize Q3IsInitialized Q3ExitAs much as possible, function parameters are ordered consistently throughout the application programming interfaces. In virtually all cases, the first parameter is a data type that corresponds to the object being operated on. When there are two or more additional parameters, they are placed in their natural or intuitive ordering.Most QuickDraw 3D functions return a status code, which is of type
TQ3Status
. A status code is eitherkQ3Success
orkQ3Failure
, indicating that the function has succeeded or failed. When a function fails, you can call a further function to get a specific error code. Alternatively, you can install an error-reporting callback routine to handle failures. See the chapter "Error Manager" for complete details on handling errors.Functions that create opaque objects usually return a function result whose type is a reference to the type of the newly created object (for instance,
TQ3CameraObject
for a new camera object). An object reference is an opaque pointer to the object. When these kinds of routines fail, they return the valueNULL
.Retained and Immediate Modes
A graphics system operates in retained mode if it retains a copy of all the data describing a model. In other words, a retained mode graphics system requires you to completely specify a model by passing model data to the system using predefined data structures. The graphics system organizes the data internally, usually in a hierarchical database. Once an object is added to that database, you can change the object only by calling specific editing routines provided by the graphics system.By contrast, a graphics system operates in immediate mode if the application itself maintains the data that describe a model. For example, original QuickDraw is a two-dimensional graphics system that operates in immediate mode. You draw objects on the screen, using QuickDraw, by calling routines that completely specify the objects to be drawn. QuickDraw does not maintain any information about a picture internally; it simply takes the data provided by the application and immediately draws the appropriate objects.
QuickDraw 3D supports both immediate and retained modes of specifying and drawing models. The principal advantage of immediate mode imaging is that the model data is immediately available to you and is not duplicated by the graphics system. The data is stored in whatever form you like, and you can change that data at any time. The main disadvantage of immediate mode imaging is that you need to maintain the sometimes quite lengthy object data, and you need to perform geometric operations on that data yourself. In addition, it can be difficult to accelerate immediate mode rendering, because you generally need to specify the entire model to draw a single frame, whether or not the entire model has changed since the previous frame. This can involve passing large amounts of data to the graphics system.
- Note
- OpenGL
Å is an example of a 3D graphics system that operates in immediate mode. QuickDraw GX is an example of a 2D graphics system that operates in retained mode. ![]()
Retained mode imaging typically supports higher levels of abstraction than immediate mode imaging and is more amenable to hardware acceleration and caching. In addition, the hierarchical arrangement of the model data allows the graphics system to perform very quick updates whenever the data is altered. To avoid duplicating data between your application and the graphics system's database, your application should match the data types of the graphics system and use the extensive editing functions to change a model's data.
Another important advantage of retained mode imaging is that it's very easy to read and write retained objects.
To create a point, for example, in retained mode, you fill in a data structure of type
TQ3PointData
and pass it to theQ3Point_New
function. This function copies the data in that structure and returns an object of typeTQ3GeometryObject
, which you use for all subsequent operations on the point. For example, to draw the point in retained mode, you pass that geometric object returned byQ3Point_New
to theQ3Geometry_Submit
function inside a rendering loop. To change the data associated with the point, you call point-editing functions, such asQ3Point_GetPosition
andQ3Point_SetPosition
. Finally, when you have finished using the point, you must callQ3Object_Dispose
to have QuickDraw 3D delete the point from its internal database.It's much simpler to draw a point in immediate mode. You do not need to call any QuickDraw 3D routine to create a point in immediate mode; instead, you merely have to maintain the point data yourself, typically in a structure of type
TQ3PointData
. To draw a point in immediate mode, you call theQ3Point_Submit
function, passing it a pointer to that structure. Note, however, that when using immediate mode, you need to know exactly what types of objects you're drawing and hardcode the appropriate routines in your source code.
In general, if most of a model remains unchanged from frame to frame, you should use retained mode imaging to create and draw the model. If, however, many parts of the model do change from frame to frame, you should probably use immediate mode imaging, creating and rendering a model on a shape-by-shape basis. You can, of course, use a combination of retained and immediate mode imaging: you can create retained objects for the parts of a model that remain static and draw quickly changing objects in immediate mode.
- Note
- Immediate mode rendering does not require any memory permanently allocated to QuickDraw 3D, but it might require QuickDraw 3D to perform temporary allocations while rendering is occurring.
![]()